package com.jaks.xpense.data;

import java.util.ArrayList;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;

import com.jaks.xpense.data.entities.TableEntity;
import com.jaks.xpense.data.entities.Tag;
import com.jaks.xpense.utils.Globals;

public class Tags extends Table {

	private static final String[] Columns = new String[] { TableEntity.Id, Tag.Order, Tag.Name };

	public Tags(Context context) {
		super(context);
	}

	@Override
	public long create(TableEntity entity) {

		Tag tag = (Tag) entity;
		int order = getMaxOrder() + 1;
		tag.setOrder(order);

		ContentValues values = tag.getContentValues();
		return db.insert(Tag.TableName, null, values);
	}

	@Override
	public boolean update(TableEntity entity) {

		ContentValues values = entity.getContentValues();
		return db.update(Tag.TableName, values, where(entity.getId()), null) > 0;
	}

	@Override
	public boolean delete(long id) {
		return db.delete(Tag.TableName, where(id), null) > 0;
	}

	@Override
	public Cursor readAll() {
		return db.query(Tag.TableName, Columns, null, null, null, null, Tag.Order + " ASC");
	}

	@Override
	public TableEntity read(long id) throws SQLException {
		Tag entity = null;

		Cursor cursor = db.query(true, Tag.TableName, Columns, where(id), null, null, null, null, null);

		if ((cursor.getCount() > 0) && cursor.moveToFirst()) {
			entity = new Tag();
			entity.setId(cursor.getLong(cursor.getColumnIndex(TableEntity.Id)));
			entity.setOrder(cursor.getInt(cursor.getColumnIndex(Tag.Order)));
			entity.setName(cursor.getString(cursor.getColumnIndex(Tag.Name)));
		}
		if (cursor != null && !cursor.isClosed()) {
			cursor.close();
		}

		return entity;
	}

	public ArrayList<Tag> readAllToList() throws SQLException {

		ArrayList<Tag> tags = new ArrayList<Tag>();
		Cursor cursor = db.query(Tag.TableName, Columns, null, null, null, null, Tag.Order + " ASC");

		if ((cursor.getCount() > 0) && cursor.moveToFirst()) {

			do {
				Tag entity = new Tag();
				entity.setId(cursor.getLong(cursor.getColumnIndex(TableEntity.Id)));
				entity.setOrder(cursor.getInt(cursor.getColumnIndex(Tag.Order)));
				entity.setName(cursor.getString(cursor.getColumnIndex(Tag.Name)));

				tags.add(entity);
			} while (cursor.moveToNext());
		}

		if (cursor != null && !cursor.isClosed()) {
			cursor.close();
		}

		return tags;
	}

	public long getId(String name) {

		long id = 0;
		Cursor cursor = db.query(true, Tag.TableName, Columns, where(name), null, null, null, null,
		    null);

		if ((cursor.getCount() > 0) && cursor.moveToFirst()) {
			id = cursor.getLong(cursor.getColumnIndex(TableEntity.Id));
		}

		if (cursor != null && !cursor.isClosed()) {
			cursor.close();
		}

		return id;
	}

	public int getMaxOrder() {

		int id = 0;
		String[] columns = new String[] { "Max(tagOrder) tagOrder" };
		Cursor cursor = db.query(Tag.TableName, columns, null, null, null, null, null);

		if (cursor.moveToFirst()) {
			id = cursor.getInt(cursor.getColumnIndex(Tag.Order));
		}

		if (cursor != null && !cursor.isClosed()) {
			cursor.close();
		}

		return id;
	}

	public void updateTagOrder(int from, int to) throws SQLException {

		if (from == to)
			return;

		Cursor tags = readAll();
		int count = tags.getCount();

		if ((from < 0) || (from >= count) || (to < 0) || (to >= count))
			return;

		tags.moveToPosition(from);

		int rangeFrom, rangeTo;
		String increment = " +1 ";

		if (from > to) {
			rangeFrom = to;
			rangeTo = from;
		} else {
			rangeFrom = from;
			rangeTo = to;
			increment = " -1 ";
		}

		String query = "Update " + Tag.TableName + " Set " + Tag.Order + " = " + Tag.Order + increment;
		query += " Where " + Tag.Order + " Between " + rangeFrom + " And " + rangeTo;
		db.execSQL(query);

		long rowId = tags.getLong(tags.getColumnIndexOrThrow(TableEntity.Id));
		query = "Update " + Tag.TableName + " Set " + Tag.Order + " = " + to + " Where "
		    + TableEntity.Id + " = " + rowId;
		db.execSQL(query);

		tags.close();
	}

	protected String where(String name) {
		return Tag.Name + " like " + Globals.toDbString(name);
	}
}
